﻿using System;
using System.Collections.Generic;
using System.Text;
using SharpDiary.Core.Data;
using SharpDiary.Core.Utility;
using System.Data;
using System.ComponentModel;
using SharpDiary.Core.ORMapping;

namespace SharpDiary.Core.Security
{
    public class AuthorityManager
    {
        #region Fields & Properties

        public static readonly string SHARP_DIARY_PRIVATE_KEY = "~#xiao1ei#~";

        private string _userName = string.Empty;

        private string _password = string.Empty;

        private UserInfo _currentUserInfo;

        /// <summary>
        /// 获取登记成功的用户信息。
        /// </summary>
        public UserInfo CurrentUserInfo
        {
            get { return _currentUserInfo; }
        }

        #endregion

        #region Constructors

        public AuthorityManager()
        {

        }

        #endregion

        #region Methods

        private bool _isPasswordEncrypedOnMD5 = false;

        /// <summary>
        /// 异步身份验证。需响应事件: SignInCompleted 以获取此方法的调用结果。
        /// </summary>
        /// <param name="userName">用户名称</param>
        /// <param name="password">密码</param>
        /// <param name="isPasswordEncrypedOnMD5">密码是否已经过MD5加密</param>
        public void SignInAsync(string userName, string password, bool isPasswordEncrypedOnMD5)
        {
            _isPasswordEncrypedOnMD5 = isPasswordEncrypedOnMD5;
            _userName = userName;
            _password = password;

            BackgroundWorker worker = new BackgroundWorker();
            worker.DoWork += new DoWorkEventHandler(worker_DoWork);
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
            worker.RunWorkerAsync();
        }

        private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            SignInCompletedEventArgs result = e.Result as SignInCompletedEventArgs;
            OnSignInCompleted(this, result);
        }

        private void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            SignInCompletedEventArgs args = new SignInCompletedEventArgs();
            string failReason = string.Empty;
            args.Success = SignIn(_userName, _password, ref failReason);
            args.FailReason = failReason;

            e.Result = args;
        }

        /// <summary>
        /// 身份验证。
        /// </summary>
        /// <param name="userName">用户名称</param>
        /// <param name="password">密码</param>
        /// <param name="failReason">未通过身份验证的原因。</param>
        /// <returns>是否通过身份验证。</returns>
        protected virtual bool SignIn(string userName, string password, ref string failReason)
        {
            failReason = string.Empty;

            if (string.IsNullOrEmpty(userName))
            {
                failReason = "用户名称不能为空，请您输入用户名称。";
                return false;
            }

            StringBuilder sql = new StringBuilder();
            sql.AppendLine("SELECT * from UserInfo");
            sql.AppendLine("where SignInUserName = @userName");

            DataAccessService das = Utils.GetDataAccessServiceInstance();

            try
            {
                _currentUserInfo = DbObjectMappingHelper.Query<UserInfo>(sql.ToString(), das.CreateParameter("@userName", DbType.String, userName));
            }
            catch (Exception ex)
            {
                failReason = "身份验证失败。详细原因: " + ex.Message;
                MessageBoxHelper.ShowException(ex);

                return false;
            }

            if (_currentUserInfo == null || string.IsNullOrEmpty(_currentUserInfo.SignInUserName))
            {
                failReason = "用户名称或密码不正确。";
                return false;
            }

            string rightUserName = _currentUserInfo.SignInUserName;
            string rightPassword = _currentUserInfo.Password; //md5 密文

            //将明文密码经MD5加密处理
            if (!_isPasswordEncrypedOnMD5)
            {
                password = MD5Helper.GenerateToMD5HexString(password);
            }

            //区分大小写验证用户名称和密码
            if (rightUserName == userName && password == rightPassword)
            {
                return true;
            }
            else
            {
                failReason = "用户名称或密码不正确。";
            }

            return false;
        }

        #endregion

        #region Events

        /// <summary>
        /// 完成身份验证后触发此事件。
        /// </summary>
        public event EventHandler<SignInCompletedEventArgs> SignInCompleted;

        protected virtual void OnSignInCompleted(object sender, SignInCompletedEventArgs e)
        {
            if (SignInCompleted != null)
            {
                SignInCompleted(sender, e);
            }
        }

        #endregion
    }

    /// <summary>
    /// 事件 SignInCompleted 参数。
    /// </summary>
    public class SignInCompletedEventArgs : EventArgs
    {
        private bool _success = false;

        /// <summary>
        /// 获取或设置是否通过了身份验证。
        /// </summary>
        public bool Success
        {
            get { return _success; }
            set { _success = value; }
        }

        private string _failReason = string.Empty;

        /// <summary>
        /// 获取或设置未通过身份验证的原因。
        /// </summary>
        public string FailReason
        {
            get { return _failReason; }
            set { _failReason = value; }
        }

        public SignInCompletedEventArgs() { }


    }
}
